﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using FarPoint.Win.Spread;
using FarPoint.Win.Spread.Model;
using FarPoint.Win.Spread.UndoRedo;

namespace SpreadDesigner
{
    /// <summary>
    /// Undo action for clear range
    /// </summary>
    internal class ClearRangeUndoAction : UndoAction
    {
        private SheetView sheet;
        private CellRange range;
        private object[,] oldvalues;
        public ClearRangeUndoAction()
        {
        }
        /// <summary>
        /// Create the ClearRangeUndoAction
        /// </summary>
        /// <param name="sheet">Sheet to clear</param>
        /// <param name="range">Range to clear</param>
        public ClearRangeUndoAction(SheetView sheet, CellRange range)
        {
            this.sheet = sheet;
            this.range = range;
        }
        /// <summary>
        /// Do the ClearRangeUndoAction (use FpSpread.UndoManager.PerformUndoAction, do not call directly)
        /// </summary>
        /// <param name="sender">sending object when used in ActionMap and InputMap to map a key</param>
        /// <returns>true if succeed, false otherwise</returns>
        public override bool PerformUndoAction(object sender)
        {
            if( sender != null )
            {
                sheet = ((SpreadView)sender).GetSheetView();
                range = sheet.GetSelection(0);
            }
            if( SaveUndoState())
            {
                sheet.ClearRange(range.Row, range.Column, range.RowCount, range.ColumnCount, true);
                return true;
            }
            return false;
        }

        protected override bool SaveUndoState()
        {
            if (sheet != null && range != null)
                oldvalues = sheet.GetArray(range.Row, range.Column, range.RowCount, range.ColumnCount);
            return oldvalues != null;
        }

        public override bool Undo(object sender)
        {
            if (oldvalues != null)
            {
                sheet.SetArray(range.Row, range.Column, oldvalues);
                return true;
            }
            return false;
        }
    }
    public class PropertyChangeUndoAction : UndoAction
    {
        private object target;
        private string property;
        private object oldvalue;
        private object newvalue;
        private PropertyInfo pi;
        public PropertyChangeUndoAction(object target, string property, object newvalue)
        {
            this.target = target;
            this.property = property;
            this.newvalue = newvalue;
            pi = target.GetType().GetProperty(property);
        }
        public override bool PerformUndoAction(object sender)
        {
            if (SaveUndoState())
            {
                pi.SetValue(target, newvalue, null);
                return true;
            }
            return false;
        }

        protected override bool SaveUndoState()
        {
            if (pi != null)
            {
                oldvalue = pi.GetValue(target, null);
                return true;
            }
            return false;
        }

        public override bool Undo(object sender)
        {
            if (pi != null)
            {
                pi.SetValue(target, oldvalue, null);
                return true;
            }
            return false;
        }
    }
}
